package com.sagframe.sagacity.sqltoy.plus.multi.interfaces;
import com.sagframe.sagacity.sqltoy.plus.conditions.interfaces.SFunction;

import java.util.List;
import java.util.Map;

public interface LambdaFunc<Children extends LambdaFunc<Children>> {

    /**
     * 分组：GROUP BY 字段, ...
     * <p>例: groupBy("id")</p>
     *
     * @param condition 执行条件
     * @param column    单个字段
     * @return children
     */
    <T> Children groupBy(boolean condition, SFunction<T, ?> column);

    default <T> Children groupBy(SFunction<T, ?> column) {
        return groupBy(true, column);
    }

    /**
     * 分组：GROUP BY 字段, ...
     * <p>例: groupBy(Arrays.asList("id", "name"))</p>
     *
     * @param condition 执行条件
     * @param columns   字段数组
     * @return children
     */
    <T> Children groupBy(boolean condition, List<SFunction<T, ?>> columns);

    default <T> Children groupBy(List<SFunction<T, ?>> columns) {
        return groupBy(true, columns);
    }

    default <T> Children groupBy(SFunction<T, ?> column, SFunction<T, ?>... columns) {
        return groupBy(true, column, columns);
    }

    /**
     * 分组：GROUP BY 字段, ...
     */
    <T> Children groupBy(boolean condition, SFunction<T, ?> column, SFunction<T, ?>... columns);

    /**
     * 排序：ORDER BY 字段, ... ASC
     * <p>例: orderByAsc(true, "id")</p>
     *
     * @param condition 执行条件
     * @param column    单个字段
     * @return children
     */
    default <T> Children orderByAsc(boolean condition, SFunction<T, ?> column) {
        return orderBy(condition, true, column);
    }

    default <T> Children orderByAsc(SFunction<T, ?> column) {
        return orderByAsc(true, column);
    }

    /**
     * 排序：ORDER BY 字段, ... ASC
     * <p>例: orderByAsc(true, Arrays.asList("id", "name"))</p>
     *
     * @param condition 执行条件
     * @param columns   字段数组
     * @return children
     */
    default <T> Children orderByAsc(boolean condition, List<SFunction<T, ?>> columns) {
        return orderBy(condition, true, columns);
    }

    default <T> Children orderByAsc(List<SFunction<T, ?>> columns) {
        return orderByAsc(true, columns);
    }

    default <T> Children orderByAsc(SFunction<T, ?> column, SFunction<T, ?>... columns) {
        return orderByAsc(true, column, columns);
    }

    /**
     * 排序：ORDER BY 字段, ... ASC
     */
    default <T> Children orderByAsc(boolean condition, SFunction<T, ?> column, SFunction<T, ?>... columns) {
        return orderBy(condition, true, column, columns);
    }

    /**
     * 排序：ORDER BY 字段, ... DESC
     * <p>例: orderByDesc(true, "id")</p>
     *
     * @param condition 执行条件
     * @param column    字段
     * @return children
     */
    default <T> Children orderByDesc(boolean condition, SFunction<T, ?> column) {
        return orderBy(condition, false, column);
    }

    default <T> Children orderByDesc(SFunction<T, ?> column) {
        return orderByDesc(true, column);
    }

    /**
     * 排序：ORDER BY 字段, ... DESC
     * <p>例: orderByDesc(true, Arrays.asList("id", "name"))</p>
     *
     * @param condition 执行条件
     * @param columns   字段列表
     * @return children
     */
    default <T> Children orderByDesc(boolean condition, List<SFunction<T, ?>> columns) {
        return orderBy(condition, false, columns);
    }

    default <T> Children orderByDesc(List<SFunction<T, ?>> columns) {
        return orderByDesc(true, columns);
    }

    default <T> Children orderByDesc(SFunction<T, ?> column, SFunction<T, ?>... columns) {
        return orderByDesc(true, column, columns);
    }

    /**
     * 排序：ORDER BY 字段, ... DESC
     */
    default <T> Children orderByDesc(boolean condition, SFunction<T, ?> column, SFunction<T, ?>... columns) {
        return orderBy(condition, false, column, columns);
    }

    /**
     * 排序：ORDER BY 字段, ...
     * <p>例: orderBy(true, "id")</p>
     *
     * @param condition 执行条件
     * @param isAsc     是否是 ASC 排序
     * @param column    单个字段
     * @return children
     */
    <T> Children orderBy(boolean condition, boolean isAsc, SFunction<T, ?> column);

    /**
     * 排序：ORDER BY 字段, ...
     * <p>例: orderBy(true, Arrays.asList("id", "name"))</p>
     *
     * @param condition 执行条件
     * @param isAsc     是否是 ASC 排序
     * @param columns   字段列表
     * @return children
     */
    <T> Children orderBy(boolean condition, boolean isAsc, List<SFunction<T, ?>> columns);

    /**
     * 排序：ORDER BY 字段, ...
     */
    <T> Children orderBy(boolean condition, boolean isAsc, SFunction<T, ?> column, SFunction<T, ?>... columns);

    /**
     * ignore
     */
    default <T> Children having(String sqlHaving, Map<String, Object> paramMap) {
        return having(true, sqlHaving, paramMap);
    }

    /**
     * HAVING ( sql语句 )
     * <p>例1: having("sum(age) &gt; 10")</p>
     * <p>例2: having("sum(age) &gt; {0}", 10)</p>
     *
     * @param condition 执行条件
     * @param sqlHaving sql 语句
     * @param paramMap    参数数据
     * @return children
     */
    <T> Children having(boolean condition, String sqlHaving, Map<String, Object> paramMap);
}
